﻿#include "Scheduler/EventScheduler.h"
#include "Scheduler/ThreadPool.h"
#include "Scheduler/UsageEnvironment.h"
#include "Live/MediaSessionManager.h"
#include "Live/RtspServer.h"
#include "Live/H264FileMediaSource.h"
#include "Live/H264FileSink.h"
#include "Live/AACFileMediaSource.h"

#include "Live/AACFileSink.h"
#include "Base/Log.h"

int main() {
    /*
    * 
    程序初始化了一份session名为test的资源，访问路径如下

    // rtp over tcp
    ffplay -i -rtsp_transport tcp  rtsp://127.0.0.1:8554/test

    // rtp over udp
    ffplay -i rtsp://127.0.0.1:8554/test

     C++的初始化参数列中可以调用父类构造函数，初始化父类对象，跳转函数实现的时候，别忘了这些父类的构造函数
    
    */

    srand(time(NULL));//时间初始化

    //事件调度器，在本程序中，事件都是描述符的事件，每个事件都绑定在描述符上，除了TimerEvent和TriggerEvent
    //类比qt,文件描述符就像信号，回调函数就像槽，或者说，文件描述符就是信号源
    EventScheduler* scheduler = EventScheduler::createNew(EventScheduler::POLLER_SELECT);//网络模型、计时器管理器

    //std::vector的构造函数可以接受两个参数：初始大小和初始值,也可以只接受一个参数:初始大小
    ThreadPool* threadPool = ThreadPool::createNew(1);
    MediaSessionManager* sessMgr = MediaSessionManager::createNew();
    UsageEnvironment* env = UsageEnvironment::createNew(scheduler, threadPool);

    //服务器，timerfd会加入select监听，rtsp连接会加入select监听，而rtp连接则由timerfd驱动，只负责发送数据
    //此服务器大量使用了列表、map、队列，timerfd触发后，查找计时器map，使用合适的计时器，而计时器事件的回调，又会
    //遍历sink所属的rtp连接实例，发送数据，其他例子如连接关闭的列表，数据帧列表，线程池任务列表
    Ipv4Address rtspAddr("127.0.0.1", 8554);
    RtspServer* rtspServer = RtspServer::createNew(env, sessMgr,rtspAddr);

    LOGI("----------session init start------");
    {
        //本服务器只支持拉流播放，媒体资源来自服务器存储的文件，SessionManager--session--track--sink--source
        MediaSession* session = MediaSession::createNew("test");
        //打开一个媒体文件
        MediaSource* source = H264FileMediaSource::createNew(env, "../data/daliu.h264");
        Sink* sink = H264FileSink::createNew(env, source);
        session->addSink(MediaSession::TrackId0, sink);

        source = AACFileMeidaSource::createNew(env, "../data/daliu.aac");
        sink = AACFileSink::createNew(env, source);
        session->addSink(MediaSession::TrackId1, sink);

        //session->startMulticast(); //多播，使用RtpInstance
        sessMgr->addSession(session);//SessionManager--session--track--sink--source
    }
    LOGI("----------session init end------");


    rtspServer->start();

    env->scheduler()->loop();
    return 0;

}